Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

3장. Query Builder의 등장

Raw Query 방식에서는
SQL을 문자열로 직접 작성하고 조합해야 했다.

특히 조건이 많아질수록
문자열을 이어붙이는 방식은 빠르게 복잡해졌다.

let query = "SELECT * FROM users WHERE 1=1";

if (email) {
  query += ` AND email = '${email}'`;
}

if (status) {
  query += ` AND status = '${status}'`;
}

이 방식은 유연하지만,
코드의 안정성과 가독성 측면에서 부담이 커진다.


SQL을 구조적으로 다루려는 시도

이 문제를 해결하기 위해 등장한 것이
👉 Knex.js 와 같은 Query Builder 방식이다

문자열을 직접 조합하는 대신
코드 구조를 통해 SQL을 만들어가는 방식이다.

const users = await knex('users')
  .where('email', email)
  .andWhere('status', status);

이제 SQL은 문자열이 아니라
메서드 체이닝 형태로 표현된다.


무엇이 달라졌는가

가장 큰 변화는
👉 “SQL을 만드는 방식”이다

Raw Query에서는

  • 문자열을 직접 조합했고

Query Builder에서는

  • 구조를 기반으로 쿼리를 생성한다

즉,

👉 SQL 작성 방식이 “문자열 → 구조”로 바뀐다


Query Builder의 핵심 특징

이 방식은 다음과 같은 특징을 가진다.

  • 메서드 체이닝 기반 쿼리 생성
  • 조건을 코드로 분기 처리 가능
  • 파라미터 바인딩 자동 처리

특히 중요한 점은
👉 SQL Injection을 기본적으로 방지할 수 있다는 것이다.


동적 조건 처리의 변화

1장에서 문제가 되었던 동적 조건 처리도
훨씬 자연스럽게 바뀐다.

const query = knex('users');

if (email) {
  query.where('email', email);
}

if (status) {
  query.where('status', status);
}

const users = await query;

문자열을 이어붙이지 않고
조건을 “추가”하는 형태로 바뀐다.


Query Builder의 장점

이 방식은 Raw Query의 여러 문제를 개선한다.

  • SQL Injection 방지
  • 동적 조건 처리 용이
  • 코드 가독성 향상
  • 쿼리 생성 로직을 구조적으로 관리 가능

특히 조건이 많은 쿼리에서
차이가 크게 드러난다.


하지만 여전히 남아있는 한계

Query Builder는 많은 문제를 해결했지만
완전히 새로운 접근 방식은 아니다.

여전히 다음과 같은 특징을 가진다.

  • SQL 구조를 이해해야 한다
  • 데이터베이스에 대한 의존이 남아 있다
  • 복잡한 쿼리는 오히려 더 읽기 어려워질 수 있다

예를 들어 JOIN이나 서브쿼리가 많아질 경우
코드가 오히려 더 길어지기도 한다.


여전히 SQL 중심이다

중요한 점은
이 방식이 SQL을 없앤 것이 아니라

👉 SQL을 “조금 더 안전하게 만드는 것”에 가깝다는 점이다

즉,

  • 사고 방식은 여전히 SQL 중심이고
  • 데이터 접근 방식 자체가 바뀐 것은 아니다

다음 단계로의 흐름

개발자들은 다시 고민하게 된다.

  • SQL을 계속 알아야 하는 구조가 맞는가?
  • 데이터를 객체처럼 다룰 수는 없는가?
  • 비즈니스 로직과 데이터 접근을 더 분리할 수는 없는가?

이 고민에서 등장한 것이
👉 객체 중심의 데이터 접근 방식

이다.